package logger

import (
	"fmt"

	"github.com/gin-gonic/gin"
)

// contextLogger 为日志追加 request_id 前缀，便于定位请求
type contextLogger struct {
	requestID string
	logger    Logger
}

// WithRequestID 为底层 logger 创建带 request_id 的包装
func (l *zapLogger) WithRequestID(c interface{}) Logger {
	requestID := extractRequestID(c)
	if requestID == "" {
		return l
	}

	return &contextLogger{
		requestID: requestID,
		logger:    l,
	}
}

// extractRequestID 从 gin.Context 或字符串中解析 request_id
func extractRequestID(c interface{}) string {
	if ctx, ok := c.(*gin.Context); ok && ctx != nil {
		if id, exists := ctx.Get("request_id"); exists {
			if requestID, ok := id.(string); ok {
				return requestID
			}
		}
	}

	if id, ok := c.(string); ok {
		return id
	}

	return ""
}

// ===== Logger 接口实现 =====

func (cl *contextLogger) Debug(msg string) {
	cl.logger.Debug(cl.formatMsg(msg))
}

func (cl *contextLogger) Info(msg string) {
	cl.logger.Info(cl.formatMsg(msg))
}

func (cl *contextLogger) Warn(msg string) {
	cl.logger.Warn(cl.formatMsg(msg))
}

func (cl *contextLogger) Error(msg string) {
	cl.logger.Error(cl.formatMsg(msg))
}

func (cl *contextLogger) Debugf(format string, args ...interface{}) {
	cl.logger.Debugf(cl.formatMsg(format), args...)
}

func (cl *contextLogger) Infof(format string, args ...interface{}) {
	cl.logger.Infof(cl.formatMsg(format), args...)
}

func (cl *contextLogger) Warnf(format string, args ...interface{}) {
	cl.logger.Warnf(cl.formatMsg(format), args...)
}

func (cl *contextLogger) Errorf(format string, args ...interface{}) {
	cl.logger.Errorf(cl.formatMsg(format), args...)
}

func (cl *contextLogger) With(fields map[string]interface{}) Logger {
	if fields == nil {
		fields = make(map[string]interface{})
	}
	if cl.requestID != "" {
		fields["request_id"] = cl.requestID
	}
	return &contextLogger{
		requestID: cl.requestID,
		logger:    cl.logger.With(fields),
	}
}

func (cl *contextLogger) Named(name string) Logger {
	return &contextLogger{
		requestID: cl.requestID,
		logger:    cl.logger.Named(name),
	}
}

func (cl *contextLogger) WithRequestID(c interface{}) Logger {
	if id := extractRequestID(c); id != "" {
		return &contextLogger{
			requestID: id,
			logger:    cl.logger,
		}
	}
	return cl
}

func (cl *contextLogger) formatMsg(msg string) string {
	if cl.requestID != "" {
		return fmt.Sprintf("[%s] %s", cl.requestID, msg)
	}
	return msg
}
